#ifndef UTILS_FACTORY_MAP_HPP
#define UTILS_FACTORY_MAP_HPP

#include <map>
#include <cassert>

namespace utils
{

	// TODO: Document
	// TODO: UNit test
template< typename ID, typename Func>
class factory_map
{
public:
	typedef ID id_type;
	typedef Func function_type;
	typedef std::map< id_type, function_type> map_type;
	typedef typename map_type::const_iterator const_iterator;

	void register_constructor( const id_type& id, const function_type& function)
	{
		assert( !this->has_constructor_for( id));
		constructors_.insert( std::make_pair( id, function));
	}

	void unregister_constructor( const id_type& id)
	{
		constructors_.erase( constructors_.find( id));
	}

	bool has_constructor_for( const id_type& id) const
	{
		return constructors_.end() != constructors_.find( id);
	}

	const function_type& operator[]( const id_type& id) const 
	{ 
		assert( this->has_constructor_for( id));
		map_type::const_iterator i = constructors_.find( id);
		return i->second;
	}

	const_iterator begin() const { return constructors_.begin(); }
	const_iterator end() const { return constructors_.end(); }

private:
	map_type constructors_;
};

} // namespace utils

#endif // UTILS_FACTORY_MAP_HPP
